﻿#include "MirScrollingLabel.h"
#include "../Forms/Client.CMain.h"
#include "../../Shared/Functions/Functions.h"

namespace Client::MirControls
{

Regex *const MirScrollingLabel::R = new Regex(R"(<(.*?/\@.*?)>)");
Regex *const MirScrollingLabel::C = new Regex(R"({(.*?/.*?)})");

    MirScrollingLabel::MirScrollingLabel() : _textLabel(std::vector<MirLabel*>(12)), _textButtons(std::vector<MirLabel*>())
    {
    }

    void MirScrollingLabel::NewText(std::vector<std::string> &lines, bool resetIndex)
    {
        if (resetIndex)
        {
            Index = 0;
            CurrentLines = lines;
        }

        for (auto t : _textButtons)
        {
            t->Dispose();
        }

        for (MirLabel *t : _textLabel.Where([&] (std::any t)
        {
            return t != nullptr;
        }))
        {
            t->Text = "";
        }

        _textButtons.clear();

        int lastLine = lines.size() > VisibleLines ? ((VisibleLines + Index) > lines.size() ? lines.size() : (VisibleLines + Index)) : lines.size();

        for (int i = Index; i < lastLine; i++)
        {
            MirLabel *tempVar = new MirLabel();
            tempVar->setFont(Font);
            tempVar->setDrawFormat(TextFormatFlags::WordBreak);
            tempVar->setVisible(true);
            tempVar->setParent(this);
            Size tempVar2(getSize()->Width, 20);
            tempVar->setSize(&tempVar2);
            Point tempVar3(0, 0 + (i - Index) * 15);
            tempVar->setLocation(&tempVar3);
            tempVar->setNotControl(true);
            _textLabel[i - Index] = tempVar;

            if (i >= lines.size())
            {
                _textLabel[i - Index]->setText("");

                delete tempVar;
                continue;
            }

            std::string currentLine = lines[i];

            std::vector<Match*> matchList = R->Matches(currentLine)->Cast<Match*>().ToList();
            matchList.AddRange(C->Matches(currentLine)->Cast<Match*>());

            int oldLength = currentLine.length();

            for (auto match : matchList.OrderBy([&] (std::any o)
            {
                return o::Index;
            }).ToList())
            {
                int offSet = oldLength - currentLine.length();

                Capture *capture = match::Groups[1].Captures[0];
                std::vector<std::string> values = StringHelper::split(capture->Value, '/');
//C# TO C++ CONVERTER TODO TASK: There is no C++ equivalent to the .NET String 'Insert' method unless assigning to the string instance:
                currentLine.erase(capture->Index - 1 - offSet, capture->Length + 2)->Insert(capture->Index - 1 - offSet, values[0]);
                std::string text = currentLine.substr(0, capture->Index - 1 - offSet) + " ";
                Size *size = TextRenderer::MeasureText(CMain::Graphics, text, _textLabel[i - Index]->getFont(), _textLabel[i - Index]->getSize(), TextFormatFlags::TextBoxControl);

                //if (R.Match(match.Value).Success)
                //    NewButton(values[0], values[1], TextLabel[i].Location.Add(new Point(size.Width - 10, 0)));

                if (C->Match(match->Value)->Success)
                {
                    Point tempVar4(size->Width - 10, 0);
                    NewColour(values[0], values[1], Functions::Add(_textLabel[i - Index]->getLocation(), &tempVar4));
                }
            }

            _textLabel[i - Index]->setText(currentLine);
            //TextLabel[i].MouseWheel += NPCDialog_MouseWheel;

            delete tempVar;
        }
    }

    void MirScrollingLabel::NewColour(const std::string &text, const std::string &colour, Point *p)
    {
        Color *textColour = Color::FromName(colour);

        MirLabel *temp = new MirLabel();
        temp->setAutoSize(true);
        temp->setVisible(true);
        temp->setParent(this);
        temp->setLocation(p);
        temp->setText(text);
        temp->setForeColour(textColour);
        temp->setFont(Font);
        //temp.MouseWheel += NPCDialog_MouseWheel;

        _textButtons.push_back(temp);

//C# TO C++ CONVERTER TODO TASK: A 'delete temp' statement was not added since temp was passed to a method or constructor. Handle memory management manually.
    }
}
